<template>
  <div class="app-container">
    <div class="filter-container">
      <div class="header">
        <el-radio-group
          v-model="house"
          class="filter-item"
          @change="onHouseChange">

          <el-radio-button
            v-for="item in houses"
            :disabled="item.disabled"
            :key="item.id"
            :label="item.id">
            {{ item.text }}
          </el-radio-button>
        </el-radio-group>
        <el-button class="filter-item" style="margin-left: 30px;"
            type="danger" icon="el-icon-bell"
            @click="onStopAlarm" >
            解除报警
        </el-button>

        <div class="actions">
          <el-button class="filter-item" style="margin-left: 10px;"
             type="success" icon="el-icon-plus"
             @click="onScanAttach" >
            添加设备
          </el-button>

          <el-button class="filter-item"
             type="success" icon="el-icon-video-play" @click="onStartAll">
            一键开启
          </el-button>
          <el-button class="filter-item" style="margin-left: 10px;" type="danger" icon="el-icon-video-pause" @click="onStopAll">
            一键停止
          </el-button>

          <el-button class="filter-item" style="margin-left: 10px;"
             type="primary" icon="el-icon-magic-stick"
             @click="onScanRemove">
            扫码解绑
          </el-button>

          <el-checkbox class="filter-item" style="margin-left: 40px"
            v-model="isAutoRefresh" label="自动刷新">
          </el-checkbox>

          <i class="filter-item" :class="listLoading ? 'el-icon-loading' : 'el-icon-check'"
            style="margin-left: 20px;">
          </i>
        </div>
      </div>
    </div>

    <div class="status-tpr">
      老化房实时温度：
      <span style="margin-left: 20px;" v-for="(t, index) in tprs" :key="index">{{t}}℃</span>
    </div>

    <el-table :data="list" border fit highlight-current-row style="width: 100%"
        :cell-class-name="tableCellClassName" :row-class-name="deviceRowClassName"
        @selection-change="onSelectionChanged">
      <el-table-column type="expand">
        <template slot-scope="{row}">
          <el-form label-position="left" label-width="100px">
            <el-col :span="12">
            <el-form-item label="设定电压">
              <span>{{ row.presetVoltage }}</span>
            </el-form-item>
            <el-form-item label="设定电流">
              <span>{{ row.presetCurrent }}</span>
            </el-form-item>
            <el-form-item label="设定时间">
              <span>{{ row.presetDuration ? (row.presetDuration / 3600) : '' }}</span>
            </el-form-item>
            <el-form-item label="实时温度">
              <span>{{ row.temperature }}</span>
            </el-form-item>

            <el-form-item label="错误代码">
              <span>{{ row.errorCode || '-'}}</span>
            </el-form-item>
            <el-form-item label="错误消息">
              <span>{{ row.agingErrorCode | getAgingError}}</span>
            </el-form-item>
            <el-form-item label="错误备注">
              <div v-for="(remark, index) in (row.agingErrorRemark || '').split('\n')" :key="index">
                {{remark}}
              </div>
            </el-form-item>
            <el-form-item v-if="!isOperator && (row.status == 5 || row.status == 9)">
              <el-button type="success" @click="addRemark(row)">
                添加备注
              </el-button>
            </el-form-item>
            </el-col>

            <el-col :span="12">
            <el-form-item label="电压上限">
              <span>{{ row.voltageUpper }}</span>
            </el-form-item>
            <el-form-item label="电压下限">
              <span>{{ row.voltageLower }}</span>
            </el-form-item>
            <el-form-item label="电流上限">
              <span>{{ row.currentUpper }}</span>
            </el-form-item>
            <el-form-item label="电流下限">
              <span>{{ row.currentLower }}</span>
            </el-form-item>

            <el-form-item label="停止时间">
              <span>{{ row.agingStopTime }}</span>
            </el-form-item>
            </el-col>
          </el-form>
        </template>
      </el-table-column>
      <el-table-column type="index" min-width="60" align="center"/>

      <el-table-column type="selection" min-width="60" align="center"></el-table-column>

      <el-table-column min-width="100" label="通道" align="center">
        <template slot-scope="{row}">
          <span>{{ row.channel }}</span>
        </template>
      </el-table-column>

      <el-table-column min-width="80" label="电源" align="center">
        <template slot-scope="{row}">
          <span v-if="row.powerState && row.status != 2"><i class="el-icon-warning-outline power-state"></i></span>
          <span v-else>-</span>
        </template>
      </el-table-column>

      <el-table-column min-width="120" label="状态" align="center">
        <template slot-scope="{row}">
          <el-tag
            :type="row.status | statusTypeFilter" effect="dark">
            {{ row.status | statusFilter }}
          </el-tag>
        </template>
      </el-table-column>

      <el-table-column min-width="150" label="设备SN" align="center">
        <template slot-scope="{row}">
          <span>{{ row.sn }}</span>
        </template>
      </el-table-column>
      <el-table-column v-if="showAllColumns" min-width="200" label="开启时间" align="center">
        <template slot-scope="{row}">
          <span>{{ row.agingStartTime || '-'}}</span>
        </template>
      </el-table-column>
      <el-table-column min-width="120" label="运行时长" align="center">
        <template slot-scope="{row}">
          <span v-if="row.agingStopTime">{{ new Date(row.agingStartTime) | timeDuration(new Date(row.agingStopTime))}}</span>
          <span v-else-if="row.agingStartTime">{{ new Date(row.agingStartTime) | timeDuration}}</span>
          <span v-else>{{ '-' }}</span>
        </template>
      </el-table-column>

      <el-table-column min-width="100" label="实时电压" align="center">
        <template slot-scope="{row}">
          <span>{{ row.voltage }}</span>
          <img :src="audio" class="audio" v-if="isDataError(row, 'v')">
        </template>
      </el-table-column>
      <el-table-column min-width="100" label="实时电流" align="center">
        <template slot-scope="{row}">
          <span>{{ row.current }}</span>
          <img :src="audio" class="audio" v-if="isDataError(row, 'c')">
        </template>
      </el-table-column>
      <el-table-column min-width="100" label="老化结果" align="center">
        <template slot-scope="{row}">
          <span>{{ row.agingResult == 1 ? '正常' : ( row.agingResult == 2 ? '异常' : '-') }}</span>
        </template>
      </el-table-column>

      <el-table-column align="center" label="操作" min-width="430" fixed="right">
        <template slot-scope="{row}">
          <div v-if="row.id">
            <el-button type="success" size="small" icon="el-icon-data-line" @click="handleViewDetails(row)">
              详情
            </el-button>
            <el-button type="primary"
              v-if="row.status != 3"
                       :disabled="row.status == 5 || row.status == 9"
                       size="small" icon="el-icon-video-play" @click="onStartDevice(row)">
              开启
            </el-button>
            <el-button type="danger"
              v-if="row.status != 3"
                       :disabled="row.status == 5 || row.status == 9"
                       size="small" icon="el-icon-video-pause" @click="onCloseDevice(row)">
              停止
            </el-button>

            <el-dropdown style="margin-left: 10px;" @command="handleDropDownCommand($event, row)">
              <el-button type="normal" size="small">
                <i class="el-icon-arrow-down"></i>
              </el-button>

              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item
                  :disabled="row.status == 2"
                  icon="el-icon-delete" command="remove" v-if="isAdmin">
                    解绑SN
                </el-dropdown-item>
                <el-dropdown-item
                  v-if="!isOperator"
                  :disabled="row.status != 1"
                  icon="el-icon-setting"
                  command="config">
                  参数配置
                </el-dropdown-item>

                <el-dropdown-item
                  command="alarm"
                  v-if="isDebug">
                  告警测试
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
          <div v-else>
            <el-button
              type="danger" size="small" icon="el-icon-video-pause" @click="onCloseDevice(row)">
              停止
            </el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <el-radio-group v-model="houseGroup" class="filter-item house-group" @change="onHouseGroupChange">
      <el-radio-button label="A车">&nbsp;A车&nbsp;</el-radio-button>
      <el-radio-button label="B车">&nbsp;B车&nbsp;</el-radio-button>
      <el-radio-button label="C车">&nbsp;C车&nbsp;</el-radio-button>
      <el-radio-button label="D车">&nbsp;D车&nbsp;</el-radio-button>
    </el-radio-group>

    <el-dialog
      :title="`${viewingRow ? viewingRow.channel : ''}  / ${viewingRow ? viewingRow.sn : ''} 设备运行图`"
      :visible.sync="dialogFormVisible">
      <el-date-picker
        v-model="chartDateStart"
        @change="onDateChanged"
        type="datetime"
        :clearable="false"
        placeholder="选择开始时间" />

      <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
        <line-chart :chart-data="chartData" />
      </el-row>

      <div slot="footer" class="dialog-footer">
        <el-button type="success" icon="el-icon-download" @click="exportData">
          数据导出
        </el-button>

        <el-button @click="dialogFormVisible = false">
          关闭
        </el-button>
      </div>
    </el-dialog>

    <!-- 参数配置对话框 -->
    <el-dialog
      title="参数配置"
      :visible.sync="configDialogVisible"
      width="300px"
    >
      <el-form ref="configForm" :model="configForm" label-width="150px">
        <el-form-item label="设定时间（小时）">
          <el-input v-model="configForm.presetDuration"></el-input>
        </el-form-item>
        <el-form-item label="设定电压（V）">
          <el-input v-model="configForm.presetVoltage"></el-input>
        </el-form-item>
        <el-form-item label="设定电流（A）">
          <el-input v-model="configForm.presetCurrent"></el-input>
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="configDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="onConfirmConfig">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 扫码添加设备对话框 -->
    <el-dialog
      :visible.sync="scanAttachDialogVisible" width="70%"
      :close-on-click-modal="false">

      <div style="width:100%;color:#E6A23C;font-size:30px;text-align:center;font-weight:bold;margin-bottom: 20px;">
        正在扫码中，请勿关闭窗口
      </div>
      <el-form :model="attachDeviceForm" style="text-align:center;">
        <el-row :gutter="10">
          <el-col :md="10">
            <el-form-item>
              <el-input placeholder="通道码"
                        ref="attachChannelBox"
                        v-model="attachDeviceForm.channel"
                        tabindex="1"
                        style="ime-mode:active"
                        @blur="onAttachChannelBlur"
                        @keypress.native="onAttachChannelKeyPress"
              >
                <template slot="prepend">通道码：</template>
              </el-input>
            </el-form-item>
          </el-col>

          <el-col :md="10">
            <el-form-item>
              <el-input placeholder="设备SN"
                        ref="attachSnBox"
                        v-model="attachDeviceForm.sn"
                        tabindex="2"
                        @keypress.native="onAttachSnKeyPress"
              >
                <template slot="prepend">设备号：</template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :md="4" v-if="!isOperator">
            <el-button type="success" @click="generateSn">生成SN</el-button>
          </el-col>
        </el-row>
      </el-form>

      <el-table
        ref="newDeviceTable"
        :data="newDevices"
        empty-text="-"
        :row-class-name="newDeviceRowClassName"
        @selection-change="onNewDeviceSelectionChange"
        border fit style="width: 100%">
        <el-table-column type="index" width="50" align="center"/>

        <el-table-column type="selection" align="center">
        </el-table-column>

        <el-table-column label="通道码" align="center">
          <template slot-scope="{row}">
            <span>{{ row.channel }}</span>
          </template>
        </el-table-column>

        <el-table-column label="设备SN" min-width="150" align="center">
          <template slot-scope="{row}">
            <span>{{ row.sn }}</span>
          </template>
        </el-table-column>

        <el-table-column label="设备型号" min-width="100" align="center">
          <template slot-scope="{row}">
            <span>{{ row.model }}</span>
          </template>
        </el-table-column>

        <el-table-column label="设定电压" align="center">
          <template slot-scope="{row}">
            <span>{{ row.presetVoltage }}</span>
          </template>
        </el-table-column>

        <el-table-column min-width="120" label="电压范围(V)" align="center">
        <template slot-scope="{row}">
          <span>{{ row.voltageLower }}</span>
          <span class="line">/</span>
          <span>{{ row.voltageUpper }}</span>
        </template>
      </el-table-column>

        <el-table-column label="设定电流"  align="center">
          <template slot-scope="{row}">
            <span>{{ row.presetCurrent }}</span>
          </template>
        </el-table-column>

        <el-table-column min-width="120" label="电流范围(A)" align="center">
        <template slot-scope="{row}">
          <span>{{ row.currentLower }}</span>
          <span class="line">/</span>
          <span>{{ row.currentUpper }}</span>
        </template>
      </el-table-column>

        <el-table-column label="设定时间"  align="center">
          <template slot-scope="{row}">
            <span>{{ row.presetDuration ? (row.presetDuration / 3600) : ''}}</span>
          </template>
        </el-table-column>

        <el-table-column width="120" label="已老化次数" align="center">
          <template slot-scope="{row}">
            <span>{{ row.agingTimes }}</span>
          </template>
        </el-table-column>
      </el-table>

      <span slot="footer" class="dialog-footer">
        <el-button @click="scanAttachDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="onAttach">添加</el-button>
      </span>
    </el-dialog>

    <!-- 扫码移除设备对话框 -->
    <el-dialog
      :visible.sync="scanRemoveDialogVisible" width="50%"
      :close-on-click-modal="false">

      <div style="width:100%;color:#E6A23C;font-size:30px;text-align:center;font-weight:bold;margin-bottom: 20px;">
        正在扫码中，请勿关闭窗口
      </div>
      <el-form :model="deviceForm" style="text-align:center;">
        <el-row :gutter="10">
          <el-col :md="12">
            <el-form-item>
              <el-input placeholder="通道码"
                        ref="removeChannelBox"
                        v-model="deviceForm.channel"
                        tabindex="1"
                        style="ime-mode:active"
                        @keypress.native="onChannelKeyPress"
              >
                <template slot="prepend">通道码：</template>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <el-table
        ref="channelTable"
        :data="channels"
        @selection-change="onChannelSelectionChange"
        border fit style="width: 100%">
        <el-table-column type="index" width="50" align="center"/>
        <el-table-column type="selection" align="center">
        </el-table-column>

        <el-table-column label="通道码" align="center">
          <template slot-scope="{row}">
            <span>{{ row.channel }}</span>
          </template>
        </el-table-column>

        <el-table-column label="设备SN" align="center">
          <template slot-scope="{row}">
            <span>{{ row.sn }}</span>
          </template>
        </el-table-column>
        <el-table-column label="设备状态" align="center">
          <template slot-scope="{row}">
            <span>{{ row.status | statusFilter}}</span>
          </template>
        </el-table-column>
      </el-table>

      <span slot="footer" class="dialog-footer">
        <el-button @click="onCancel">取 消</el-button>
        <el-button type="primary" @click="onDetach">解绑</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import LineChart from './LineChart'
import StatusTag from '@/components/StatusTag'
import {
  getStatus,
  getDeviceByChannel,
  getLogs, startDevice, stopDevice, removeDevice, restoreDevice,
  stopAll, startAll, sendAlarm,
  batchDetach,
  configDevice,
  remarkDevice,
  getChannelStatus,
  getPowerState,
  getDeviceBySn,
  batchAdd,
  exportDeviceData,
  stopAlarm, getTemperatures
} from '@/api/device'

import { updateSysConfigs } from '@/api/config'
import { getNextSn } from '@/utils/auth'
import audio from '@/assets/audio.svg'
import { parseTime } from '@/utils'

const CHANNELS = {
  'A03': {
    'A车': ['A0301', 'A0302', 'A0303', 'A0304', 'A0305', 'A0306', 'A0307', 'A0308', 'A0309'],
    'B车': ['A0310', 'A0311', 'A0312', 'A0313', 'A0314', 'A0315', 'A0316', 'A0317', 'A0318'],
    'C车': ['A0319', 'A0320', 'A0321', 'A0322', 'A0323', 'A0324', 'A0325', 'A0326', 'A0327'],
    'D车': ['A0328', 'A0329', 'A0330', 'A0331', 'A0332', 'A0333', 'A0334', 'A0335', 'A0336']
  },

  'A04': {
    'A车': ['A0401', 'A0402', 'A0403', 'A0404', 'A0405', 'A0406', 'A0407', 'A0408'],
    'B车': ['A0409', 'A0410', 'A0411', 'A0412', 'A0413', 'A0414', 'A0415', 'A0416'],
    'C车': ['A0417', 'A0418', 'A0419', 'A0420', 'A0421', 'A0422', 'A0423', 'A0424'],
    'D车': ['A0425', 'A0426', 'A0427', 'A0428', 'A0429', 'A0430', 'A0431', 'A0432']
  }
}

const CABINETS = {
  'A03': {
    'A车': 'A03X',
    'B车': 'A03X',
    'C车': 'A03Y',
    'D车': 'A03Y',
  },

  'A04': {
    'A车': 'A04X',
    'B车': 'A04X',
    'C车': 'A04Y',
    'D车': 'A04Y',
  },
}

export default {
  name: 'Status',
  components: { LineChart, StatusTag },

  filters: {
    statusTypeFilter(status) {
      if (!status) return 'info'; // 通道空闲

      const statusMap = {
        1: 'plain',
        2: 'success',
        3: 'normal',
        4: 'info',
        5: "danger",
        9: 'danger'
      }
      return statusMap[status]
    },
  },

  computed: {
    isOperator() {
      let roles = this.$store.getters.roles;

      return (roles || []).some(role => {
        return (role == 'operator')
      })
    },

    isAdmin() {
      let roles = this.$store.getters.roles;

      return (roles || []).some(role => {
        return (role == 'admin')
      })
    }
  },

  watch: {
    dialogFormVisible: function(value) {
      if (value) {
        let that = this;
        that._getChartData()
        this.chartTimer = setInterval(() => {
          that._getChartData()
    　　}, 6000)
      } else {
          if (this.chartTimer) {
            clearInterval(this.chartTimer)
            this.chartTimer = null
          }

          this.viewingRow = null;
      }
    },

    isAutoRefresh: function(v) {
      if (v == true) {
        if (this.timer) {
          clearInterval(this.timer)
        }

        this.timer = setInterval(() => {
          this.getList()
    　　}, 6000)
      } else {
        if (this.timer) {
          clearInterval(this.timer)
        }
      }
    }
  },

  data() {
    let yesterday = new Date();
    yesterday.setTime(yesterday.getTime() - 24 * 3600 * 1000);

    return {
      tprs: [],

      configForm: {
        id:       null,
        presetVoltage: '',
        presetCurrent: '',
        presetDuration: ''
      },

      newDevices: [
      ],

      selectedNewDeviceRows: [
      ],

      houseGroup: 'A车',
      channels: [],
      attachDeviceForm: {
        channel: '',
        sn: '',
        status: ''
      },
      deviceForm: {
        channel: '',
        sn: '',
        status: ''
      },
      scanRemoveDialogVisible: false,
      scanAttachDialogVisible: false,
      configDialogVisible: false,
      isAutoRefresh: false,
      list: null,
      listLoading: false,
      dialogFormVisible: false,
      showAllColumns: true,
      chartData: {
        times: [],
        currents: [],
        voltages: [],
        temperatures: []
      },

      isDebug: false,

      houses: [
        {id: 'A01', text: '老化房A01', disabled: true},
        {id: 'A02', text: '老化房A02', disabled: true},
        {id: 'A03', text: '老化房A03', disabled: false},
        {id: 'A04', text: '老化房A04', disabled: false},
      ],
      house: 'A03',
      timer: null,
      chartTimer: null,
      viewingRow: null,
      selectedRows: [],

      selectedChannels: [],

      chartDateStart: yesterday,
      audio
    }
  },
  created() {
    let { house, group } = this.$route.query;

    // console.log(house, group)

    this.house = house || 'A03';
    this.houseGroup = group || 'A车';

    this.getList()
  },

  mounted() {

  },

  destroyed() {
    clearInterval(this.timer)

    if (this.chartTimer) {
      clearInterval(this.chartTimer)
      this.chartTimer = null
    }
  },

  methods: {
    isDataError(row, type) {
      // 只显示老化中的数据异常
      if (row.status != 2) return false;

      let now = new Date();
      const gap = now.getTime() / 1000 - new Date(row.agingStartTime).getTime() / 1000;
      // 开机10分钟内不报警
      if (gap < 60 * 10) {
        return false
      } else {
        if (type == 'v') {
          if (row.voltage < row.voltageLower) {
            return true;    // 电压低于阈值，显示提示图片
          }
        }

        if (type == 'c') {
          if (row.current < row.currentLower) {
            return true;    // 电流低于阈值，显示提示图片
          }
        }
      }

      return false
    },

    handleDropDownCommand(event, row) {
      if (event == 'remove') {
        this.onRemoveDevice(row);
      } else if (event == 'config') {
        this.onConfig(row);
      } else if (event == 'alarm') {
        this.onSendAlarm(row);
      }
    },

    onConfig(row) {
      this.configForm = {
        id: row.id,
        presetVoltage: row.presetVoltage,
        presetCurrent: row.presetCurrent,
        presetDuration: row.presetDuration ? parseInt(row.presetDuration / 3600) : ''
      }

      this.configDialogVisible = true;
    },

    onConfirmConfig() {
      // 时间转化成秒
      let params = Object.assign({}, this.configForm)
      params.presetDuration = params.presetDuration * 3600

      configDevice(params).then(() => {
        this.$message({
          message: '修改配置成功！',
          type: 'success'
        })
      }).finally(() => {
        this.configDialogVisible = false;

        this.getList()
      })
    },

    exportData() {
      let row = this.viewingRow

      if (!this.chartDateStart) {
        let yesterday = new Date();
        yesterday.setTime(yesterday.getTime() - 24 * 3600 * 1000);
        this.chartDateStart = yesterday
      }

      exportDeviceData(row, this.chartDateStart).then(res => {
        const url = window.URL.createObjectURL(new Blob([res.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', res.headers['content-disposition'].substring(20));
        document.body.appendChild(link);
        link.click();
      })
    },

    getList() {
      if (!CHANNELS[this.house] || !CHANNELS[this.house][this.houseGroup]) {
        console.error(`没有老化房的车间配置：${this.house} ${this.houseGroup}`)
        return
      }

      let channels = CHANNELS[this.house][this.houseGroup];
      let cabinet = CABINETS[this.house][this.houseGroup];

      this._getListByChannels(channels, cabinet);
      this._getCabinetTemperatures(cabinet);
    },

    _getChartData() {
      let that = this;
      let row = this.viewingRow

      if (!this.chartDateStart) {
        let yesterday = new Date();
        yesterday.setTime(yesterday.getTime() - 24 * 3600 * 1000);
        this.chartDateStart = yesterday
      }

      getLogs(row.id, this.chartDateStart).then(res => {
        let logs = res.data.data;

        that.chartData.times = logs.map(l => l.created)
        that.chartData.voltages = logs.map(l => l.voltage)
        that.chartData.currents = logs.map(l => l.current)
        that.chartData.temperatures = logs.map(l => l.temperature)
        that.chartData.device = Object.assign({}, row)
      })
    },

    _getListByHouse(house) {
      this.listLoading = true
      getStatus(house).then(res => {
        let data = res.data.data
        this.list = data
      }).finally(() => {
        this.listLoading = false
      })
    },

    _getCabinetTemperatures(cabinet) {
      getTemperatures(cabinet).then(res => {
        let tprs = res.data.data || [];
        // A03X - [4]  - 1号房
        // A03Y - [3]  - 2号房
        // A04X - [4]  - 3号房
        // A04Y - [1]  - 4号房

        if (tprs.length == 4) {
          if (cabinet == 'A03X') {
            tprs[3] = '(1号房)' + tprs[3];
          }

          if (cabinet == 'A03Y') {
            tprs[2] = '(2号房)' + tprs[2];
          }

          if (cabinet == 'A04X') {
            tprs[3] = '(3号房)' + tprs[3];
          }

          if (cabinet == 'A04Y') {
            tprs[0] = '(4号房)' + tprs[0];
          }
        }

        this.tprs = tprs;
      })
    },

    _getListByChannels(channels, cabinet) {
      this.listLoading = true

      Promise.all([
        getChannelStatus(channels),
        getPowerState(cabinet),
      ]).then(values => {
        let data1 = values[0].data.data;

        let data2 = values[1].data.data;

        data1.forEach(d => {
          if (/A0[1-4]\d{2}/.test(d.channel)) {
            let index = Number(d.channel.substring(3, 5)) - 1
            // A03: 1-35  A04: 1-32
            if (d.channel.startsWith('A03')) {
              index = index % 18;
            }

            if (d.channel.startsWith('A04')) {
              index = index % 16;
            }

            if (index >= 0 && index < data2.length) {
              d.powerState = data2[index];
            }
          }
        })

        this.list = data1
      }).finally(() => {
        this.listLoading = false
      })

      /*
      getChannelStatus(channels).then(res => {
        let data = res.data.data
        this.list = data
      }).finally(() => {
        this.listLoading = false
      })
      */
    },

    handleViewDetails(row) {
      this.viewingRow = row;
      this.dialogFormVisible = true
    },

    onHouseChange(house) {
      if (!this.houseGroup) {
        this.houseGroup = 'A车'
      }

      if (!CHANNELS[this.house] || !CHANNELS[this.house][this.houseGroup]) {
        console.error(`没有老化房的车间配置：${this.house} ${this.houseGroup}`)
        return
      }

      let channels = CHANNELS[this.house][this.houseGroup];
      let cabinet = CABINETS[this.house][this.houseGroup];

      this._getListByChannels(channels, cabinet);
      this._getCabinetTemperatures(cabinet);
    },

    onHouseGroupChange(group) {
      if (!CHANNELS[this.house] || !CHANNELS[this.house][group]) {
        console.error(`没有老化房的车间配置：${this.house} ${group}`)
        return
      }

      let channels = CHANNELS[this.house][group];
      let cabinet = CABINETS[this.house][group];
      this._getListByChannels(channels, cabinet);
      this._getCabinetTemperatures(cabinet);
    },

    onStartDevice(device) {
      if (device.status == 2) return;

      if (!device.presetVoltage || !device.presetCurrent || !device.presetDuration) {
        this.$message({
          message: '请在逆变器信息页面，先配置好电流、电压、老化时间。',
          type: 'warning'
        })

        return
      }

      if ((device.status == 9 || device.status == 5) && (device.needRemark == 1)) {
        this.$message({
          message: '请设置错误备注再开机。',
          type: 'warning'
        })

        return
      }

      this.$message({
        message: '正在启动中！',
        type: 'success'
      })
      startDevice(device).then(res => {
        this.$message({
          message: '启动成功！',
          type: 'success'
        })

        this.getList()
        // this._getListByHouse(this.house)
      })
    },

    onCloseDevice(device) {
      // 通道没设备的情况，什么也不做
      if (!device.id) {
        this.$message({
          message: '关闭成功！',
          type: 'success'
        })

        return;
      }

      stopDevice(device).then(res => {
        this.$message({
          message: '关闭成功！',
          type: 'success'
        })

        this.getList()
        // this._getListByHouse(this.house)
      })
    },

    // 移除设备，通道输入框点击
    onChannelKeyPress(e) {
      if (e.code != 'Enter') {
        return
      } else {
        if (!/A0[1-4][0-3]\d/.test(this.deviceForm.channel)) {
          this.$message({
            message: `通道号错误：${this.deviceForm.channel}`,
            type: 'warning'
          })
          this.deviceForm.channel = ''

          return
        }
      }

      // 移除设备时，根据通道找设备
      getDeviceByChannel(this.deviceForm.channel).then(res => {
        let existingDevice = res.data.data
        if (!existingDevice) {
          this.$message({
            message: `通道上面未查询到设备：${this.deviceForm.channel}`,
            type: 'warning'
          })
          return
        } else {
          if (existingDevice.status == 2) {
            this.$message({
              message: `通道${this.deviceForm.channel}上面的设备${existingDevice.sn}正在老化，不能移除`,
              type: 'warning'
            })
            return
          }
        }
        existingDevice.channel = this.deviceForm.channel

        this.channels.push(existingDevice)
        this.$refs.channelTable.toggleRowSelection(existingDevice);
      }).finally(() => {
        this.deviceForm.channel = '';
        this.$refs.removeChannelBox.focus();
      });
    },

    onCancel() {
      this.scanRemoveDialogVisible = false
      this.channels = []
    },

    onDetach() {
      if (!this.selectedChannels || this.selectedChannels.length == 0) {
        return
      }

      batchDetach(this.selectedChannels).then(res => {
        this.$message({
          message: `解绑成功！`,
          type: 'success'
        })

        this.channels = []
        this.selectedChannels = []
      }).finally(() => {
        this.getList()
      })

      this.scanRemoveDialogVisible = false
    },

    onChannelSelectionChange(rows) {
      this.selectedChannels = rows;
    },

    onStartAll() {
      // 没有关联通道的设备不启动
      let rows = this.selectedRows.filter(row => !!row.id)

      startAll(rows).then(res => {
        this.$message({
          message: '正在启动！',
          type: 'success'
        })

        this.getList()
        // this._getListByHouse(this.house)
      })
    },

    onStopAll() {
      // 没有关联通道的设备不启动
      let rows = this.selectedRows.filter(row => !!row.id)

      stopAll(rows).then(res => {
        this.$message({
          message: '正在关闭！',
          type: 'success'
        })

        this.getList()
        // this._getListByHouse(this.house)
      })
    },

    onSelectionChanged(selections) {
      this.selectedRows = selections
    },

    onRemoveDevice(device) {
      this.$confirm(`确认要解绑 ${device.sn}？`).then(() => {
        removeDevice(device).then(() => {
          this.$message({
            message: '移除成功！',
            type: 'success'
          })

          this.getList()
          // this._getListByHouse(this.house)
        });
      })
    },

    onSendAlarm(device) {
      sendAlarm(device).then(res => {
        this.$message({
          message: '告警成功！',
          type: 'success'
        })
      })
    },

    onScanAttach() {
      this.scanAttachDialogVisible = true;

      this.$nextTick(() => {
        this.$refs.attachChannelBox.focus();
      })
    },

    onScanRemove() {
      this.scanRemoveDialogVisible = true;

      this.$nextTick(() => {
        this.$refs.removeChannelBox.focus();
      })
    },

    onDateChanged() {
      this._getChartData()
    },

    addRemark(row) {
      console.log('time:', parseTime(new Date()))

      var that = this
      this.$prompt('请输入错误备注', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }).then(({ value }) => {
        value = value + " " + parseTime(new Date());

        if (!row.agingErrorRemark) {
          row.agingErrorRemark = value;
        } else {
          row.agingErrorRemark = row.agingErrorRemark + '\n' + value;
        }

        // 发送请求，更新设备信息
        remarkDevice(row.id, row.agingErrorRemark).then(res => {
          // 添加故障备注之后，下一步确定是否解绑 / 停机，解绑设备后，设备重新进入已扫码状态
          // 产生一条新的记录
          that.confirmDettachDevice(row);

          // that.getList()
        })
      });
    },

    confirmDettachDevice(device) {
      this.$confirm(
        `是否要解绑通道【${device.channel}】和设备【${device.sn}】？不解绑的话，设备会恢复已扫码状态，可以重新开启。`,
        `提示`,
        {
          confirmButtonText:  '解绑',
          cancelButtonText:   '不解绑',
          type: 'warning'
        })
        .then(() => {
          removeDevice(device).then(() => {
            this.$message({
              message: '解绑成功！',
              type: 'success'
            })

            this.getList()
          });
        })
        .catch(() => {
          restoreDevice(device).then(() => {
            this.$message({
              message: '设备已重置。',
              type: 'info'
            });

            this.getList();
          });
        });
    },

    tableCellClassName({row, column, rowIndex, columnIndex}) {
      if (columnIndex == 8 && row.status == 2) {
          let start = new Date().getTime(); // now
          let endTime = row.agingEndTime || start;

          if ((endTime - start) / 1000 < 20 * 60) {
            return 'warning-col'
          }
      }
    },

    deviceRowClassName({row, rowIndex}) {
      if (row.status == 1) {
        return 'new-device-row';
      }

      return '';
    },

    // 添加设备相关方法
    generateSn() {
      let sn = getNextSn();

      this.attachDeviceForm.sn = sn;
      this.$refs.attachSnBox.focus();
    },

    onAttachChannelBlur(e) {
      if ((/^A0[1-4][0-3]\d$/.test(this.attachDeviceForm.channel))
          || (this.attachDeviceForm.channel == 'A8888')) {  // A8888是测试码
        getDeviceByChannel(this.attachDeviceForm.channel).then(res => {
          let existingDevice = res.data.data
          if (existingDevice) {
            this.$message({
              message: `通道上面已绑定了设备：${existingDevice.sn}`,
              type: 'warning'
            })

            this.attachDeviceForm.channel = ''
            this.$refs.attachChannelBox.focus();
          } else {
            this.$refs.attachSnBox.focus();
          }
        })
      } else {  // channel 无效
        this.attachDeviceForm.channel = ''
        this.$refs.attachChannelBox.focus();
      }
    },

    onAttachChannelKeyPress(e) {
      if (e.code == 'Enter') {
        if (!this.attachDeviceForm.channel) return;

        if ((/^A0[1-4][0-3]\d$/.test(this.attachDeviceForm.channel))
          || (this.attachDeviceForm.channel == 'A8888')) {
          getDeviceByChannel(this.attachDeviceForm.channel).then(res => {
            let existingDevice = res.data.data
            if (existingDevice) {
              this.$message({
                message: `通道上面已绑定了设备：${existingDevice.sn}`,
                type: 'warning'
              })

              this.attachDeviceForm.channel = ''
            } else {
              this.$refs.attachSnBox.focus();
            }
          })
        } else {
          this.attachDeviceForm.channel = ''
        }
      }
    },

    onAttachSnKeyPress(e) {
      if (e.code != 'Enter') {
        return;
      } else {
        if (!this.attachDeviceForm.sn) return;

        if ((this.attachDeviceForm.sn || '').length != 15) {
          this.$message({
            message: `SN错误：${this.attachDeviceForm.sn}`,
            type: 'warning'
          })
          //this.deviceForm.channel = ''
          this.attachDeviceForm.sn = ''
          //this.$refs.channelBox.focus();

          return
        }
      }

      // 只查询有过完整老化记录的设备
      getDeviceBySn(this.attachDeviceForm.sn).then(res => {
        let configData = res.data.data
        let newDevice = {
          channel: this.attachDeviceForm.channel,
          sn: this.attachDeviceForm.sn,
          agingTimes: configData.agingTimes
        }

        if (configData.configs) {
          let config = configData.configs.filter(c => c.house == this.house);

          console.log("config:", config)

          if (config && config.length > 0) {
            let c = config[0]
            newDevice.model = c.model
            newDevice.presetVoltage = c.voltage
            newDevice.presetCurrent = c.current
            newDevice.presetDuration = c.duration

            // 电流电压上下限也读出来
            newDevice.currentUpper = c.currentUpper
            newDevice.currentLower = c.currentLower
            newDevice.voltageUpper = c.voltageUpper
            newDevice.voltageLower = c.voltageLower
          }
        }

        // channel相同的，后面的覆盖前面的
        let duplicated = this.newDevices.findIndex(d => {
          return d.channel == newDevice.channel
        })
        if (duplicated >= 0) {
          this.newDevices.splice(duplicated, 1)
        }

        // SN相同的，每一条都要高亮显示
        let snDuplicated = this.newDevices.findIndex(d => {
          return d.sn == newDevice.sn
        })

        if (snDuplicated >= 0) {
          this.newDevices.forEach(d => {
            if (d.sn == newDevice.sn) {
              d.isDuplicated = true
            }
          })

          newDevice.isDuplicated = true
        }

        this.newDevices.push(newDevice)
        this.$refs.newDeviceTable.toggleRowSelection(newDevice);

      }).finally(() => {
        this.attachDeviceForm.sn = '';
        this.attachDeviceForm.channel = '';
        this.$refs.attachChannelBox.focus();
      });
    },

    onNewDeviceSelectionChange(rows) {
      this.selectedNewDeviceRows = rows;
    },

    onAttach() {
      if (!this.selectedNewDeviceRows || this.selectedNewDeviceRows.length == 0) {
        return
      }

      // 排除测试通道A8888
      for(let i = 0 ;i<this.selectedNewDeviceRows.length;i++){
        if(this.selectedNewDeviceRows[i].channel == 'A8888'){
          this.selectedNewDeviceRows.splice(i,1);
        }
      }

      console.log('devices:', this.selectedNewDeviceRows)

      // 如果选择了没有设置电流电压的设备，报错
      let hasInvalid = this.selectedNewDeviceRows.some(d => {
        return !d.presetCurrent || !d.presetVoltage || !d.presetDuration
      })

      if (hasInvalid) {
        this.$message({
          message: `列表包含未设定电流电压的设备，请取消勾选该设备！`,
          type: 'warning'
        })

        return
      }

      if (this.selectedNewDeviceRows.length == 0) {
        this.newDevices = []
        this.selectedNewDeviceRows = []
        this.scanAttachDialogVisible = false
        return
      }

      batchAdd(this.selectedNewDeviceRows).then(res => {
        this.$message({
          message: `添加成功！`,
          type: 'success'
        })

        this.newDevices = []
        this.selectedNewDeviceRows = []
      }).finally(() => {
        this.getList()
      })

      this.scanAttachDialogVisible = false
    },

    onStopAlarm() {
      let configs = []
      configs.push({
        name: 'is_alarm_on',
        value: 2,
        remark: '是否开启报警，1：开启 2：关闭'
      })

      // 把告警停止掉
      updateSysConfigs(configs).then(res => {
        this.$message({
          message: `报警关闭`,
          type: 'danger'
        });

        stopAlarm().then(res => {
          console.log("停止报警。。。")
        })
      })
    },

    newDeviceRowClassName({row, rowIndex}) {
      if (row.isDuplicated) {
        return 'warning-row';
      }

      if (row.agingTimes > 0) {
        return 'hilight-row';
      }

      return '';
    }
  }
}
</script>

<style lang="scss">
  .header {
    display: flex;

    .actions {
      flex: 1;
      text-align: right;
    }
  }

  .el-table .new-device-row {
    background: #e7faf0;
  }

  .el-table .warning-col{
    background: yellow;
  }

  .el-table .warning-row {
    background: oldlace;
  }

  .el-table .hilight-row {
    background: yellow;
  }

  .house-group {
    margin-top: 20px;

    .el-radio-button__orig-radio:checked+.el-radio-button__inner {
      /*background-color: #1890ff;*/
      /*border-color: #1890ff;*/
      background-color: #13ce66;
      border-color: #13ce66;
    }
  }

  .audio {
    width: 20px;
    height: 20px;
    background-color: #ff1100;
    border-radius: 10px;
  }

  .status-tpr {
    margin-bottom: 20px;
    margin-left: 20px;
    color: red;
  }

  .power-state {
    color: red;
    font-weight: bold;
    font-size: 18px;
  }

</style>
